// This code is hosted on http://code.google.com/p/lenthorp/
// Freely available for use in applications, but should NOT be modified
// Email all comments to lenthorpresearch@gmail.com

#ifndef quantlib_gpumcengine_hpp
#define quantlib_gpumcengine_hpp


#include <ql/pricingengine.hpp>
#include <ql/instrument.hpp>
#include <ql/instruments/oneassetoption.hpp>
#include <qt/methods/montecarlo/gpupathgenerators.hpp>

namespace QuantLib {

	//class genericArguments : public virtual PricingEngine::arguments {
	//	public:
	//		genericArguments() {}
	//		void validate() const {}
	//};

	//class genericResults : public Instrument::results {
	//	public:
	//		void reset() {
	//			Instrument::results::reset();
	//		}
	//};

	template<class ArgumentsType, class ResultsType>
	class GPUMCEngine : public GenericEngine<ArgumentsType, ResultsType> {

		public:
			
			GPUMCEngine(const boost::shared_ptr<GPUPathGenerator>& pathGenerator, int nSims);
			
			void calculate() const;

		private:
			boost::shared_ptr<GPUPathGenerator> _process;
			int _nSims;
	};

	template<class ArgumentsType, class ResultsType>
	GPUMCEngine<ArgumentsType, ResultsType>::GPUMCEngine(const boost::shared_ptr<GPUPathGenerator>& pathGenerator, int nSims)
		: _process(pathGenerator),
		_nSims(nSims) {
			//registerWith(_process);
	}

	template<class ArgumentsType, class ResultsType>
	void GPUMCEngine<ArgumentsType, ResultsType>::calculate() const {
		// Note that process must already have been initialised
		this->results_.value = static_cast<Real>(_process->generate(getArguments(), _nSims));
		//this->results_.value = _process->getValue();
	}

}

#endif


